package dao;

import anno.Component;
import pojo.Order;
import utils.JDBCUtils;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class OrderDAO extends AbstractBaseDao<Order> {

    /**
     * 分页模糊查询订单，并获取用户、影片和影院的具体信息
     *
     * @param keyword  模糊查询关键字
     * @param pageNum  当前页码
     * @param pageSize 每页记录数
     * @param userId   用户ID，如果为null则代表管理员查询所有订单
     * @return 分页查询结果
     * @throws SQLException SQL异常
     */
    public Map<String, Object> findOrdersByPageAndUserId(String keyword, int pageNum, int pageSize, Integer userId) throws SQLException {
        String sql = "SELECT o.*, u.fullname AS user_fullname, m.title AS movie_title, c.name AS cinema_name " +
                "FROM tb_orders o " +
                "JOIN tb_users u ON o.user_id = u.id " +
                "JOIN tb_showtimes s ON o.showtime_id = s.id " +
                "JOIN tb_movies m ON s.movie_id = m.id " +
                "JOIN tb_halls h ON s.hall_id = h.id " +
                "JOIN tb_cinemas c ON h.cinema_id = c.id " +
                "WHERE 1=1";
        List<Object> params = new ArrayList<>();

        if (userId != null) {
            sql += " AND o.user_id = ?";
            params.add(userId);
        }

        if (keyword != null && !keyword.isEmpty()) {
            sql += " AND o.id LIKE ?"; // 使用 id 列进行模糊查询
            params.add("%" + keyword + "%");
        }

        return findByPageAndKeyword(sql, params, pageNum, pageSize);
    }

    /**
     * 根据用户ID查询订单
     *
     * @param userId 用户ID
     * @return 符合条件的订单列表
     * @throws SQLException SQL异常
     */
    public List<Order> findByUserId(Integer userId) throws SQLException {
        return findByField("user_id", userId);
    }

    /**
     * 根据场次ID查询订单
     *
     * @param showtimeId 场次ID
     * @return 符合条件的订单列表
     * @throws SQLException SQL异常
     */
    public List<Order> findByShowtimeId(Integer showtimeId) throws SQLException {
        return findByField("showtime_id", showtimeId);
    }

    /**
     * 分页模糊查询订单的辅助方法
     *
     * @param sql      查询SQL
     * @param params   查询参数
     * @param pageNum  当前页码
     * @param pageSize 每页记录数
     * @return 分页查询结果
     * @throws SQLException SQL异常
     */
    private Map<String, Object> findByPageAndKeyword(String sql, List<Object> params, int pageNum, int pageSize) throws SQLException {
        int offset = (pageNum - 1) * pageSize;
        String countSql = "SELECT COUNT(*) FROM (" + sql + ") tmp";
        String querySql = sql + " LIMIT ?, ?";

        // 添加分页参数
        List<Object> countParams = new ArrayList<>(params);
        List<Object> queryParams = new ArrayList<>(params);
        queryParams.add(offset);
        queryParams.add(pageSize);

        // 查询符合条件的订单总数
        ResultSet rsCount = (ResultSet) JDBCUtils.execute(countSql, countParams.toArray());
        int totalRecords = 0;
        if (rsCount.next()) {
            totalRecords = rsCount.getInt(1);
        }

        // 查询符合条件的订单列表
        ResultSet rsQuery = (ResultSet) JDBCUtils.execute(querySql, queryParams.toArray());
        List<Order> orderList = new ArrayList<>();
        while (rsQuery.next()) {
            orderList.add(mapResultSetToEntity(rsQuery));
        }

        // 将数据和总记录数封装到Map中
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("data", orderList);
        resultMap.put("total", totalRecords);

        return resultMap;
    }

    @Override
    protected Order mapResultSetToEntity(ResultSet rs) throws SQLException {
        Order order = new Order();
        order.setId(rs.getInt("id"));
        order.setUserId(rs.getInt("user_id"));
        order.setShowtimeId(rs.getInt("showtime_id"));
        order.setTotalPrice(rs.getDouble("total_price"));
        order.setOrderTime(rs.getTimestamp("order_time").toLocalDateTime());
        order.setStatus(rs.getString("status"));
        order.setCreatedAt(rs.getTimestamp("created_at").toLocalDateTime());
        order.setUserFullname(rs.getString("user_fullname"));
        order.setMovieTitle(rs.getString("movie_title"));
        order.setCinemaName(rs.getString("cinema_name"));
        return order;
    }
}